package com.ruoyi.system.controller;

import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.sign.Base64;
import com.ruoyi.system.common.SpringContextHolderHandle;
import com.ruoyi.system.controller.public_api_i.IPublicApiSunPanelSystemStatus;
import com.ruoyi.system.domain.IndsvrSsoApp;
import com.ruoyi.system.domain.IndsvrSsoAppUserMap;
import com.ruoyi.system.entity.*;
import com.ruoyi.system.service.IDockerService;
import com.ruoyi.system.service.IIndsvrSsoAppService;
import com.ruoyi.system.service.IIndsvrSsoAppUserMapRootService;
import com.ruoyi.system.service.IPveService;
import com.ruoyi.system.service.sso.SimulationLogin;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


@RestController
@RequestMapping("/sso")
public class IndsvrSsoController extends BaseController {

    @Autowired
    private IIndsvrSsoAppService indsvrSsoAppService;

    @Autowired
    private IIndsvrSsoAppUserMapRootService indsvrSsoAppUserMapRootService;

    @Autowired
    private RedisCache redisCache;


    ///获取当前登录应用的信息
    @GetMapping(value = "/appinfo/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(indsvrSsoAppService.selectIndsvrSsoAppById(id));
    }

    //客户端发送参数请求授权
    @PostMapping(value = "/auth")
    public AjaxResult postAuth(@RequestBody IndsvrSsoAppUserMap ssoAppUserMap) {
        LoginUser loginUser = getLoginUser();
        SysUser user = loginUser.getUser();
        HashMap<String, String> code = indsvrSsoAppUserMapRootService.auth(ssoAppUserMap.getAppId(), ssoAppUserMap.getRedirect(), ssoAppUserMap.getState(), user);
        return success(code);
    }

    //客户端凭借code获取授权信息（用于模拟登陆和表单代填）
    @RequestMapping(value = "/accessToken")
    public HashMap<String, Object> accessToken(@RequestParam String code, String client_secret, HttpServletRequest request) throws Exception {


        byte[] decode = Base64.decode(code);
        String s = new String(decode);
        String[] split = s.split("\\.");

        if (System.currentTimeMillis() - 60000 > Long.parseLong(split[0])) {
            throw new RuntimeException("code已超时");
        }


        //0 cookie或者store 模拟登录
        //1 账户密码 表单代填，
        //2 当前用户token

        int i = (int) indsvrSsoAppUserMapRootService.switchSsoType(code);
        return switch (i) {
            case 0,99 -> success(indsvrSsoAppUserMapRootService.accessTokenBy0(code, request));//模拟登录、被登录
            case 1 -> success(indsvrSsoAppUserMapRootService.accessTokenBy1(code));
            case 2 -> indsvrSsoAppUserMapRootService.accessTokenBy2(code, client_secret);//{"access_token":null}
            default -> error("登录类型未适配");
        };
    }


    //oauth2.0 时获取用户信息的接口
    @GetMapping(value = "/profile")
    public AjaxResult profile(@RequestParam String access_token) {
        String userKey = "SSO_KEY:" + access_token;
        SysUser user = redisCache.getCacheObject(userKey);
        redisCache.deleteObject(userKey);
        if (user == null) {
            return error();
        }
        return success(user);
    }




    //////////////////下方是单点登录本系统的方法

    @RequestMapping(value = "/passiveLogin")
    public void passiveLogin(String code, String state,HttpServletRequest request, HttpServletResponse response) throws Exception {
        //state 先编码去申请code
        //此方法为认证中心回调 先解码state再用，base64后url
        byte[] decode = Base64.decode(state);

        String s = indsvrSsoAppUserMapRootService.accessTokenBy99(code, new String(decode),request);
        response.sendRedirect(s);
    }

    @RequestMapping(value = "/login")
    public void login(String state,HttpServletResponse response) throws Exception {

        //本系统单点登录
            IndsvrSsoApp indsvrSsoApp1 = new IndsvrSsoApp();
            indsvrSsoApp1.setLoginType(99L);
            List<IndsvrSsoApp> indsvrSsoApps = indsvrSsoAppService.selectIndsvrSsoAppList(indsvrSsoApp1);
            if (indsvrSsoApps==null||indsvrSsoApps.size()!=1) {
                throw new RuntimeException("被登录配置非唯一");
            }
            IndsvrSsoApp indsvrSsoApp = indsvrSsoApps.get(0);
            indsvrSsoApp = indsvrSsoAppService.selectIndsvrSsoAppById(indsvrSsoApp.getId());


            SimulationLogin.Passive bean = (SimulationLogin.Passive) SpringContextHolderHandle.getBean(Class.forName("com.ruoyi.system.service.sso."+indsvrSsoApp.getLoginFunc()));
            String invoke = bean.getCodeUrl(indsvrSsoApp);
            if (state==null||"undefined".equals(state)) {
                response.sendRedirect(invoke+"/");
            }else {
                response.sendRedirect(invoke+state);
            }

            //直接申请授权
//            IndsvrSsoApp indsvrSsoApp = indsvrSsoAppService.selectIndsvrSsoAppById(appId);
//            ///authorize?client_id=3&redirect_uri=https%3A%2F%2Fwww.indsvr.com%2Fsso%2Floading.html&state=https%3A%2F%2Fwww.indsvr.com
//            String encode = URLEncoder.encode(indsvrSsoApp.getCallbackUrl(),StandardCharsets.UTF_8);
//            String url = "/authorize?client_id="+appId+"&redirect_uri="+new String(encode)+"&state=/";



    }

}
